﻿package com.agileai.miscdp.hotweb.generator.standard;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;

import com.agileai.miscdp.MiscdpPlugin;
import com.agileai.miscdp.hotweb.database.DBManager;
import com.agileai.miscdp.hotweb.database.SqlBuilder;
import com.agileai.miscdp.hotweb.domain.Column;
import com.agileai.miscdp.hotweb.domain.ResFileValueProvider;
import com.agileai.miscdp.hotweb.domain.standard.StandardFuncModel;
import com.agileai.miscdp.hotweb.domain.standard.StandardTableModel;
import com.agileai.miscdp.hotweb.generator.Generator;
import com.agileai.miscdp.util.MiscdpUtil;
import com.agileai.util.ListUtil;
import com.agileai.util.StringUtil;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
/**
 * SQLMap文件代码生成器
 */
public class SMSqlMapGenerator implements Generator{
	private String tableName = null;
	private String sqlMapFile = null;
    private String templateDir = null;
    private String[] colNames = null;
    private String findRecordsSql = null;
    private String projectName = null;
	private StandardFuncModel funcModel = null;
    
    public SMSqlMapGenerator(String projectNam){
    	this.projectName = projectNam;
    }
    
	@SuppressWarnings("unchecked")
	private void initStandardModel(StandardTableModel tableModel){
    	try {
    		DBManager dbManager = DBManager.getInstance(this.projectName);
			SqlBuilder sqlBuilder = new SqlBuilder();
			String tableName = tableModel.getTableName();
			String nameSpace = MiscdpUtil.getValidName(tableName);
			tableModel.setNamespace(nameSpace);
			String[] primaryKeys = dbManager.getPrimaryKeys(tableName);
			
			HashMap<String, Column> columnMap = dbManager.getColumnMap(tableName);
			sqlBuilder.addColumnsMap(tableName,columnMap);
			
			tableModel.setInsertRecordSql(sqlBuilder.insertSql(tableName, colNames));
			
			List<String> paramFieldList = new ArrayList<String>();
			List<String> primaryKeyList = ListUtil.arrayToList(primaryKeys);
			paramFieldList.addAll(primaryKeyList);
			String uniqueFieldCode = funcModel.retrieveUniqueField(funcModel.getPageFormFields());
			if (StringUtil.isNotNullNotEmpty(uniqueFieldCode)){
				paramFieldList.add(uniqueFieldCode);
			}
			String[] paramFields = paramFieldList.toArray(new String[0]);
			String getRecordSql = sqlBuilder.retrieveSqlByParams(colNames,tableName,paramFields);
//			tableModel.setGetRecordSql(sqlBuilder.retrieveSql(colNames, tableName, primaryKeys));
			tableModel.setGetRecordSql(getRecordSql);
			tableModel.setUpdateRecordSql(sqlBuilder.updateSql(tableName, colNames, primaryKeys));
			tableModel.setDeleteRecordSql(sqlBuilder.deleteSql(tableName, primaryKeys));
			String listSQL = MiscdpUtil.getProcessedConditionSQL(findRecordsSql);
			tableModel.setFindRecordsSql(listSQL);
		} catch (Exception e) {
			e.printStackTrace();
		}
    }

	private void initResFileModel(StandardTableModel tableModel){
    	try {
	    	DBManager dbManager = DBManager.getInstance(this.projectName);
			SqlBuilder sqlBuilder = new SqlBuilder();
			String tableName = tableModel.getTableName();
			String nameSpace = MiscdpUtil.getValidName(tableName);
			tableModel.setNamespace(nameSpace);
			HashMap<String, Column> columnMap = dbManager.getColumnMap(tableName);
			sqlBuilder.addColumnsMap(tableName,columnMap);
			
			String[] colNames = new String[3];
	        ResFileValueProvider resFileValueProvider = funcModel.getResFileValueProvider();
	        colNames[0]= resFileValueProvider.getPrimaryKeyField();
	        colNames[1]= resFileValueProvider.getBizIdField();
	        colNames[2]= resFileValueProvider.getResIdField();
			tableModel.setInsertRecordSql(sqlBuilder.insertSql(tableName, colNames));
			
			String[] delFields = new String[2];
			delFields[0]= resFileValueProvider.getPrimaryKeyField();
			delFields[1]= resFileValueProvider.getBizIdField();
			String deleteSql = sqlBuilder.deleteResFileSql(tableName, delFields);
			tableModel.setDeleteRecordSql(deleteSql);
			
			String listSQL = sqlBuilder.getResFileRecordsSQL(tableName,resFileValueProvider);
			tableModel.setFindRecordsSql(listSQL);
		} catch (Exception e) {
			e.printStackTrace();
		}
    }	
	
	public void generate() {
		try {
			String fileName = "template";
			try {
				templateDir = FileLocator.toFileURL(Platform.getBundle(MiscdpPlugin.getPluginId()).getResource(fileName)).getFile().toString();
			} catch (IOException e) {
				e.printStackTrace();
			}
			generateStandardSQLMap();
			
			if (funcModel.getResFileValueProvider() != null){
				generateResFileSQLMap();				
			}
		} catch (Exception e) {
			MiscdpPlugin.getDefault().logError(e.getLocalizedMessage(), e);
		}
	}
	
	@SuppressWarnings({ "unchecked", "rawtypes" })	
	private void generateStandardSQLMap(){
		try {
			Configuration cfg = new Configuration();
			cfg.setDirectoryForTemplateLoading(new File(templateDir+"/standard"));
	        cfg.setObjectWrapper(new DefaultObjectWrapper());
	        Template temp = cfg.getTemplate("SqlMap.xml.ftl");
	        StandardTableModel standardTableModel = new StandardTableModel();
	        standardTableModel.setTableName(tableName);
	        this.initStandardModel(standardTableModel);
	        Map root = new HashMap();
	        root.put("table",standardTableModel);
	        FileWriter out = new FileWriter(new File(this.sqlMapFile)); 
	        temp.process(root, out);
	        out.flush();			
		} catch (Exception e) {
			MiscdpPlugin.getDefault().logError(e.getLocalizedMessage(), e);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })	
	private void generateResFileSQLMap(){
		try {
			Configuration cfg = new Configuration();
			cfg.setDirectoryForTemplateLoading(new File(templateDir+"/fileuploader"));
	        cfg.setObjectWrapper(new DefaultObjectWrapper());
	        Template temp = cfg.getTemplate("SqlMap.xml.ftl");
	        ResFileValueProvider resFileValueProvider = funcModel.getResFileValueProvider();
	        String resFileTableName = resFileValueProvider.getTableName();
	        StandardTableModel standardTableModel = new StandardTableModel();
	        standardTableModel.setTableName(resFileTableName);
	        this.initResFileModel(standardTableModel);
	        Map root = new HashMap();
	        root.put("table",standardTableModel);
	        String resSQLMapFile = MiscdpUtil.parseSqlMapPath(this.sqlMapFile)+"/"+MiscdpUtil.getValidName(resFileTableName)+".xml";
	        FileWriter out = new FileWriter(new File(resSQLMapFile)); 
	        temp.process(root, out);
	        out.flush();			
		} catch (Exception e) {
			MiscdpPlugin.getDefault().logError(e.getLocalizedMessage(), e);
		}
	}
	
	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public void setSqlMapFile(String sqlMapFile) {
		this.sqlMapFile = sqlMapFile;
	}

	public void setColNames(String[] colNames) {
		List<String> cols = new ArrayList<String>();
		ListUtil.addArrayToList(cols, colNames);
		if (cols.contains(ResFileValueProvider.FormIdValue)){
			cols.remove(ResFileValueProvider.FormIdValue);
			this.colNames = cols.toArray(new String[0]);
		}else{
			this.colNames = colNames;			
		}
	}
	public void setFindRecordsSql(String findRecordsSql) {
		this.findRecordsSql = findRecordsSql;
	}

	public void setFuncModel(StandardFuncModel funcModel) {
		this.funcModel = funcModel;
	}
}